package com.sz.biz.logistics.base.service.impl;

import com.sz.biz.common.base.dto.AreaDto;
import com.sz.biz.common.base.dto.CountryDto;
import com.sz.biz.common.base.entity.Country;
import com.sz.biz.common.base.service.AreaManager;
import com.sz.biz.common.constants.ErrorCodes;
import com.sz.biz.common.constants.LanguageCode;
import com.sz.biz.common.constants.ModuleNames;
import com.sz.biz.logistics.base.dto.AirportDto;
import com.sz.biz.logistics.base.dto.TransportModel;
import com.sz.biz.logistics.base.entity.Airport;
import com.sz.biz.logistics.base.service.AirportService;
import com.sz.common.base.cache.EntityCache;
import com.sz.common.base.constants.UserActions;
import com.sz.common.base.dao.DaoSupport;
import com.sz.common.base.dao.ParamData;
import com.sz.common.base.dto.I18nDto;
import com.sz.common.base.dto.QResultDto;
import com.sz.common.base.dto.QueryParams;
import com.sz.common.base.dto.ResultDto;
import com.sz.common.base.exception.Exceptions;
import com.sz.common.base.service.AbstractService;
import com.sz.common.base.utils.CollectionUtils;
import com.sz.common.base.utils.EntityUtils;
import com.sz.common.base.utils.StringUtils;
import com.sz.common.core.service.PrincipalLogUtils;
import com.sz.common.core.service.PrincipalUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.*;

/**
 * Function: 机场AirportServiceImpl <br>
 * Author: penghui.zheng <br>
 * Date: 2016-11-23 15:41:00
 */
@Service("airportService")
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class AirportServiceImpl extends AbstractService implements AirportService {

    @Resource(name = "daoSupport")
    private DaoSupport dao;

    @Override
    public void refreshCache() {
        EntityCache.clearNamespace("AirportMapper");
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public int saveAirport(AirportDto airportDto) {
        Airport airport = new Airport();
        EntityUtils.copyPropertiesIgnoreNull(airportDto, airport);
        airport.setTetradCode(airport.getTetradCode().toUpperCase());
        airport.setTriadCode(airport.getTriadCode().toUpperCase());
        // 检查数据不能重复
        Map<String, Object> map = new HashMap<>();
        map.put("triadCode", airport.getTriadCode());
        Airport airportExist = (Airport) dao.findForObject("AirportMapper.checkTriadCode", map);
        if (airportExist != null) {
            throw Exceptions.bizException(ErrorCodes.ERROR_BIZ_AIRPORT_TRIADCODE_EXIST);
        }
        dao.save("AirportMapper.insertSelective", airport);
        // 保存操作日志
        Map<String, Object> dataBackup = new HashMap<>();
        dataBackup.put("ADD_AIRPORT", airport);
        PrincipalLogUtils.addOperationLog(ModuleNames.BIZ, ModuleNames.BIZ_AIRPORT, UserActions.ADD, "新建机场",
                dataBackup);
        return airport.getId();
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public int updateAirport(AirportDto airportDto) {
        Airport airport = new Airport();
        EntityUtils.copyPropertiesIgnoreNull(airportDto, airport);
        airport.setTetradCode(airport.getTetradCode().toUpperCase());
        airport.setTriadCode(airport.getTriadCode().toUpperCase());
        // 检查数据不能重复
        Map<String, Object> map = new HashMap<>();
        map.put("triadCode", airport.getTriadCode());
        map.put("id", airport.getId());
        Airport airportExist = (Airport) dao.findForObject("AirportMapper.checkTriadCode", map);
        if (airportExist != null) {
            throw Exceptions.bizException(ErrorCodes.ERROR_BIZ_AIRPORT_TRIADCODE_EXIST);
        }
        dao.update("AirportMapper.updateByAirportId", airport);
        // 保存操作日志
        Map<String, Object> dataBackup = new HashMap<>();
        dataBackup.put("UPDATE_AIRPORT", airport);
        PrincipalLogUtils.addOperationLog(ModuleNames.BIZ, ModuleNames.BIZ_AIRPORT, UserActions.UPDATE, "修改机场",
                dataBackup);
        return airport.getId();
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void deleteByAirportIds(List<Integer> ids) {
        dao.update("AirportMapper.deleteByAirportIds", ids);
        // 保存操作日志
        Map<String, Object> dataBackup = new HashMap<>();
        dataBackup.put("DELETE_AIRPORT", ids);
        PrincipalLogUtils.addOperationLog(ModuleNames.BIZ, ModuleNames.BIZ_AIRPORT, UserActions.DELETE, "删除机场",
                dataBackup);

    }

    @Override
    public AirportDto findByAirportId(int id) {
        ParamData pd = new ParamData();
        List<Country> allList = dao.findForList("CountryMapper" + ".findArea", pd, Country.class);
        pd.put("id", id);
        AirportDto airportDto = (AirportDto) dao.findForObject("AirportMapper.findByAirportId", pd);
        List<I18nDto> i18n = new ArrayList<I18nDto>();
        if (airportDto != null && airportDto.getId() != null) {
            int refId = airportDto.getId();
            ParamData pdi18n = new ParamData();
            pdi18n.put("refId", refId);
            i18n = dao.findForList("AirportMapper" + ".findAirportI18n", pdi18n, I18nDto.class);
            for (Country country : allList) {
                if (airportDto.getCountryId().equals(country.getFigureCode())) {
                    airportDto.setCountryName(country.getName());
                }
            }
            airportDto.setCityName(getCityName(airportDto.getCountryId(), airportDto.getCityId()));
        }
        if (airportDto != null) {
            airportDto.setI18n(i18n);
        }
        return airportDto;
    }

    @Override
    public Airport findShortById(int id) {
        Airport airport = null;
        if (id > 0) {
            List<Airport> airportList = findShortById(Arrays.asList(id));
            if (!CollectionUtils.isEmpty(airportList)) {
                airport = airportList.get(0);
            }
        }
        return airport;
    }

    @Override
    public List<Airport> findShortById(List<Integer> ids) {
        List<Airport> airportList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(ids)) {
            ParamData pd = new ParamData();
            pd.put("ids", ids);
            airportList = dao.findForList("AirportMapper.findShortById", pd, Airport.class);

        }
        return airportList;
    }

    /**
     * 根据机场areaIds查询机场信息s
     *
     * @param airportIds airportIds
     * @return List<AirportDto>
     */
    @Override
    public List<Airport> findByAirportIds(List<Integer> airportIds) {
        Map<String, Object> map = new HashMap<>();
        map.put("list", airportIds);
        map.put("language", PrincipalUtils.getLocalLanguage());
        return dao.findForList("AirportMapper.findByAirportIds", map, Airport.class);
    }

    private String getCityName(String countryName, String cityId) {
        String cityName = "";
        ParamData pdArea = new ParamData();
        pdArea.put("id", cityId);
        if (LanguageCode.CN_UPPER.equals(countryName)) {
            AreaDto areaCnDto = (AreaDto) dao.findForObject("AreaCNMapper.findByAreaId", pdArea);
            cityName = areaCnDto.getName();
        } else {
            AreaDto areaDto = (AreaDto) dao.findForObject("AreaMapper.findByAreaId", pdArea);
            cityName = areaDto.getName();
        }
        return cityName;
    }

    @Override
    public ResultDto findAirportList(QueryParams params) {
        String language = PrincipalUtils.getLocalLanguage();
        params.setLanguage(language);
        ParamData pd = this.convertQueryParams(params);
        ParamData pdCountry = new ParamData();
        List<Country> allList = dao.findForList("CountryMapper" + ".findArea", pdCountry, Country.class);
        // 调用方法查询数据
        List<AirportDto> list = dao.findForList("AirportMapper" + ".airportListPage", pd, AirportDto.class);
        for (AirportDto airportDto : list) {
            for (Country country : allList) {
                if (airportDto.getCountryId().equals(country.getFigureCode())) {
                    airportDto.setCountryName(country.getName());
                }
            }
            ParamData pdArea = new ParamData();
            pdArea.put("id", airportDto.getCityId());
            airportDto.setCityName(getCityName(airportDto.getCountryId(), airportDto.getCityId()));
        }
        QResultDto dto = new QResultDto();
        dto.setData(list);
        dto.setPagination(pd.getPagination());
        return dto;
    }

    @SuppressWarnings("rawtypes")
    @Override
    public ResultDto findI18nByParam(QueryParams params) {
        ParamData pd = this.convertQueryParams(params);
        List entry = dao.findForList(getSqlName("findI18nByParamListPage"), pd, Map.class);
        QResultDto dto = new QResultDto(entry, pd.getPagination());
        return dto;
    }

    /**
     * 机场名称校验
     *
     * @param name
     */
    @Override
    public void checkAirportName(String name) {
        Map<String, Object> map = new HashMap<>();
        map.put("name", name);
        Airport airportExist = (Airport) dao.findForObject("AirportMapper.checkAirportName", map);
        if (airportExist != null) {
            throw Exceptions.bizException(ErrorCodes.ERROR_BIZ_AIRPORT_AIRPORTNAME_EXIST);
        }
    }

    /**
     * 机场三字码校验
     *
     * @param triadCode
     * @return
     */
    @Override
    public void checkTriadCode(String triadCode, int id) {
        Map<String, Object> map = new HashMap<>();
        map.put("triadCode", triadCode);
        if (id > 0) {
            map.put("id", id);
        }
        Airport airportExist = (Airport) dao.findForObject("AirportMapper.checkTriadCode", map);
        if (airportExist != null) {
            throw Exceptions.bizException(ErrorCodes.ERROR_BIZ_AIRPORT_TRIADCODE_EXIST);
        }
    }

    /**
     * 机场四字码校验
     *
     * @param tetradCode
     * @return
     */
    @Override
    public void checkTetradCode(String tetradCode) {
        Map<String, Object> map = new HashMap<>();
        map.put("tetradCode", tetradCode);
        Airport airportExist = (Airport) dao.findForObject("AirportMapper.checkTetradCode", map);
        if (airportExist != null) {
            throw Exceptions.bizException(ErrorCodes.ERROR_BIZ_AIRPORT_TETRADCODE_EXIST);
        }
    }

    /**
     * 机场下拉列表
     *
     * @return ResultDto
     */
    @Override
    public ResultDto shortAirportListPage(QueryParams params) {
        String language = PrincipalUtils.getLocalLanguage();
        params.setLanguage(language);
        ParamData pd = this.convertQueryParams(params);
        // 调用方法查询数据
        List<TransportModel> list = dao.findForList("AirportMapper" + ".shortAirportListPage", pd,
                TransportModel.class);
        if (list != null) {
            for (TransportModel transportModel : list) {
                Map<String, Object> map = new HashMap<>();
                map.put("language", language);
                map.put("figureCode", transportModel.getContryId());
                AreaDto areaDto = new AreaDto();
                if (!StringUtils.isEmpty(transportModel.getCityId())) {
                    map.put("id", transportModel.getCityId());
                    if (transportModel.getContryName() != null && !"CN".equals(transportModel.getContryName())) {
                        areaDto = (AreaDto) dao.findForObject("AreaMapper" + ".findByAreaId", map);
                    } else {
                        areaDto = (AreaDto) dao.findForObject("AreaCNMapper" + ".findByAreaId", map);
                    }
                    if (!ObjectUtils.isEmpty(areaDto)) {
                        transportModel.setCityName(areaDto.getName());
                    }
                }
                CountryDto countryDto = (CountryDto) dao.findForObject("CountryMapper" + ".findCountryByCode", map);
                if (!ObjectUtils.isEmpty(countryDto)) {
                    transportModel.setContryName(countryDto.getName());

                }

            }
        }
        QResultDto dto = new QResultDto();
        dto.setData(list);
        dto.setPagination(pd.getPagination());
        return dto;
    }

    /**
     * 根据国家和城市查询机场下拉列表
     *
     * @return ResultDto
     */
    @Override
    public ResultDto airportDropListPage(QueryParams params) {
        String language = PrincipalUtils.getLocalLanguage();
        params.setLanguage(language);
        ParamData pd = this.convertQueryParams(params);
        // 调用方法查询数据
        List<TransportModel> list = dao.findForList("AirportMapper" + ".AirportDropListPage", pd,
                TransportModel.class);
        if (list != null) {
            for (TransportModel transportModel : list) {
                Map<String, Object> map = new HashMap<>();
                map.put("language", language);
                map.put("figureCode", transportModel.getContryId());
                AreaDto areaDto = new AreaDto();
                if (!StringUtils.isEmpty(transportModel.getCityId())) {
                    map.put("id", transportModel.getCityId());
                    if (transportModel.getContryId() != null && !"CN".equals(transportModel.getContryId())) {
                        areaDto = (AreaDto) dao.findForObject("AreaMapper" + ".findByAreaId", map);
                    } else {
                        areaDto = (AreaDto) dao.findForObject("AreaCNMapper" + ".findByAreaId", map);
                    }
                    if (!ObjectUtils.isEmpty(areaDto)) {
                        transportModel.setCityName(areaDto.getName());
                    }
                }
                CountryDto countryDto = (CountryDto) dao.findForObject("CountryMapper" + ".findCountryByCode", map);
                if (!ObjectUtils.isEmpty(countryDto)) {
                    transportModel.setContryName(countryDto.getName());

                }

            }
        }
        QResultDto dto = new QResultDto();
        dto.setData(list);
        dto.setPagination(pd.getPagination());
        return dto;
    }


    @Autowired
    private AreaManager areaManager;

    @Override
    public List<Airport> portFliter(String country, String provinceId, String cityId) {
        Map<String, Object> map = new HashMap<>(16);
        map.put("countryId", country);
        if (!StringUtils.isEmpty(provinceId) && StringUtils.isEmpty(cityId)) {
            ResultDto dto = areaManager.findByParentId(country, provinceId, "", 1, 100);
            List<AreaDto> list = (List<AreaDto>) dto.getData();
            List<String> cityIds = EntityUtils.getStringPropListFromBeans(list, "id");
            map.put("cityIds", cityIds);
        } else {
            map.put("cityIds", Collections.singletonList(cityId));
        }


        // 调用方法查询数据
        return dao.findForList("AirportMapper.portFliter", map, Airport.class);
    }

    /**
     * 根据三字码查询机场信息(精确匹配)
     *
     * @param triadCode 三字码
     * @return 机场信息
     */
    @Override
    public Airport findAirPortByTriadCode(String triadCode, String countryId) {
        Airport airport = null;
        if (!StringUtils.isEmpty(triadCode)) {
            ParamData pd = new ParamData();
            pd.put("countryId", countryId);
            pd.put("triadCode", triadCode);
            airport = (Airport) dao.findForObject("AirportMapper" + ".findAirPortByTriadCode", pd);
        }
        return airport;
    }


    @Override
    protected String getMapperNamespace() {
        return "AirportMapper";
    }
}
